using System;
using System.Collections.Generic;
using System.Text;
using System.Windows.Forms;
using System.Drawing;

using CodePlex.SpaceBlock.UI.Controls;
using System.ComponentModel;

namespace CodePlex.SpaceBlock.UI
{
    public class ActionManager
    {
        public event EventHandler<CancelEventArgs> Synchronizing;

        private readonly ContextMenuStrip _contextMenu;
        private readonly ImageList _images;
        private readonly ToolStrip _toolbar;

        private readonly Dictionary<string, ToolStripItem> _menuItems = new Dictionary<string, ToolStripItem>();
        private readonly Dictionary<string, ToolStripItem> _toolbarButtons = new Dictionary<string, ToolStripItem>();
        private readonly Dictionary<string, int> _imageIndexes = new Dictionary<string, int>();
        private readonly Dictionary<string, Keys?> _shortcutKeys = new Dictionary<string, Keys?>();
        private readonly Dictionary<string, EventHandler> _handlers = new Dictionary<string, EventHandler>();

        private readonly List<ISupportDialogKeys> _anchors;

        public ActionManager(ISupportDialogKeys anchor, ImageList images, ContextMenuStrip contextMenu, ToolStrip toolbar)
        {
            _anchors = new List<ISupportDialogKeys>();

            _anchors.Add(anchor);

            _images = images;
            _contextMenu = contextMenu;
            _toolbar = toolbar;


            if (_toolbar != null)
            {
                _toolbar.ImageList = _images;
            }

            _contextMenu.ImageList = _images;

            _contextMenu.Opening += delegate(object sender, System.ComponentModel.CancelEventArgs e)
            {
                this.OnSynchronizing(sender, e);
            };

           
            
        }


        protected void OnSynchronizing(object sender, System.ComponentModel.CancelEventArgs e)
        {
            if (this.Synchronizing != null)
            {
                this.Synchronizing(sender, e);
            }
        }


        public IEnumerable<string> Actions
        {
            get
            {
                return _handlers.Keys;
            }
        }

        public void BindTo(Control control)
        {
            control.ContextMenuStrip = _contextMenu;
        }

        public void SetEnabled(string name, bool value)
        {
            if (_toolbar != null && _toolbarButtons.ContainsKey(name))
            {
                _toolbarButtons[name].Enabled = value;
            }
            if (_menuItems.ContainsKey(name))
            {
               _menuItems[name].Enabled = value;
            }
        }

        public void SetVisible(string name, bool value)
        {
            if (_toolbar != null && _toolbarButtons.ContainsKey(name))
            {
                _toolbarButtons[name].Visible = value;
            }
            if (_menuItems.ContainsKey(name))
            {
                _menuItems[name].Visible = value;
            }
        }

        public void SetChecked(string name, bool value)
        {
           if (!_menuItems.ContainsKey(name))
           {
               return;
           }
           ToolStripMenuItem item = _menuItems[name] as ToolStripMenuItem;
           if (item == null)
           {
               return;
           }

           if (item.DropDownItems.Count == 0)
           {
               item.Checked = value;
           }
           else
           {
               if (!value)
               {
                   this.ClearChecks(item);
               }
           }
        }

        public Icon GetIcon(string name)
        {
            return UIUtils.GetIcon(_images.Images[_imageIndexes[name]]);
        }

        public void NewSubAction(string parent, string name, string text, int imageIndex, Keys? shortcutKey, EventHandler handler)
        {

            ToolStripMenuItem parentMenu = _menuItems[parent] as ToolStripMenuItem;

             //  menu item
            ToolStripMenuItem item = new ToolStripMenuItem();
            item.Size = new System.Drawing.Size(139, 22);
            item.Text = text;
            item.Click += handler;
            item.ImageIndex = imageIndex;
            parentMenu.DropDownItems.Add(item);
          
             _menuItems.Add(name, item);

        }

        public void NewAction(string name, string text, int imageIndex, Keys? shortcutKey, EventHandler handler)
        {
            //  menu item
            ToolStripMenuItem item = new ToolStripMenuItem();
            item.Size = new System.Drawing.Size(139, 22);
            item.Text = text;
            item.Click += handler;
            item.ImageIndex = imageIndex;
            _contextMenu.Items.Add(item);

            _menuItems.Add(name, item);

            if (_toolbar != null)
            {
                //  toolstrip button
                ToolStripButton button = new ToolStripButton();
                button.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image;
                button.ImageTransparentColor = System.Drawing.Color.Magenta;
                button.Size = new System.Drawing.Size(23, 22);
                button.Text = text;
                button.ImageIndex = imageIndex;
                button.Click += handler;

                _toolbar.Items.Add(button);

                _toolbarButtons.Add(name, button);

            }

            _imageIndexes.Add(name, imageIndex);


            // shortcut key
            if (shortcutKey != null)
            {
                foreach (ISupportDialogKeys anchor in _anchors)
                {
                    anchor.ProcessingDialogKey += delegate(object sender, DialogKeyEventArgs e)
                    {
                        if (e.KeyData == shortcutKey && this.IsEnabled(name))
                        {
                            handler(null, EventArgs.Empty);
                        }
                    };
                }
            }
            _shortcutKeys.Add(name, shortcutKey);

            _handlers.Add(name, handler);
        }

        public void NewSeparator(string name)
        {

            //  menu item
            ToolStripSeparator menuItem = new ToolStripSeparator();
            menuItem.Name = name;
            _menuItems.Add(name, menuItem);

            if (_toolbar != null)
            {
                //  toolstrip button
                ToolStripSeparator stripItem = new ToolStripSeparator();
                stripItem.Name = name;
                _toolbar.Items.Add(stripItem);
                _toolbarButtons.Add(name, stripItem);
            }
            _contextMenu.Items.Add(menuItem);

            _handlers.Add(name, null);

        }


        public void AddAnchor(ISupportDialogKeys anchor)
        {
            _anchors.Add(anchor);

            foreach (string name in _shortcutKeys.Keys)
            {
                string nameCopy = name;
                anchor.ProcessingDialogKey += delegate(object sender, DialogKeyEventArgs e)
                {
                    if (e.KeyData == _shortcutKeys[nameCopy] && this.IsEnabled(nameCopy))
                    {
                        _handlers[nameCopy](null, EventArgs.Empty);
                    }
                };
            }
        }


        public void Run(string action)
        {
            if (!_handlers.ContainsKey(action))
            {
                return;
            }

            _handlers[action](null, EventArgs.Empty);
        }











        private void ClearChecks(ToolStripMenuItem item)
        {
            item.Checked = false;
            foreach (ToolStripMenuItem child in item.DropDownItems)
            {
                this.ClearChecks(child);
            }
        }

        private bool IsEnabled(string name)
        {
            if (_toolbar != null)
            {
                return _toolbarButtons[name].Enabled;
            }
            else
            {
                return false;
            }
        }



      
    }
}
